module can_bsp
( 
  input  logic        clk,
  input  logic        rst,
  input  logic        sample_point,
  input  logic        sampled_bit,
  input  logic        sampled_bit_q,
  input  logic        tx_point,
  input  logic        hard_sync,
  input  logic  [7:0] addr,
  input  logic  [7:0] data_in,
  output logic  [7:0] data_out,
  input  logic        fifo_selected,
  input  logic        reset_mode,
  input  logic        listen_only_mode,
  input  logic        acceptance_filter_mode,
  input  logic        extended_mode,
  input  logic        self_test_mode,
  input  logic        release_buffer,
  input  logic        tx_request,
  input  logic        abort_tx,
  input  logic        self_rx_request,
  input  logic        single_shot_transmission,
  output logic        tx_state,
  output logic        tx_state_q,
  input  logic        overload_request,     
  output logic       overload_frame,       
  input  logic        read_arbitration_lost_capture_reg,
  input  logic        read_error_code_capture_reg,
  output logic [7:0] error_capture_code,
  input  logic  [7:0] error_warning_limit,
  input  logic        we_rx_err_cnt,
  input  logic        we_tx_err_cnt,
  output logic       rx_idle,
  output logic       transmitting,
  output logic       transmitter,
  output logic       go_rx_inter,
  output logic       not_first_bit_of_inter,
  output logic       rx_inter,
  output logic       set_reset_mode,
  output logic       node_bus_off,
  output logic       error_status,
  output logic [8:0] rx_err_cnt,
  output logic [8:0] tx_err_cnt,
  output logic       transmit_status,
  output logic       receive_status,
  output logic       tx_successful,
  output logic       need_to_tx,
  output logic       overrun,
  output logic       info_empty,
  output logic       set_bus_error_irq,
  output logic       set_arbitration_lost_irq,
  output logic [4:0] arbitration_lost_capture,
  output logic       node_error_passive,
  output logic       node_error_active,
  output logic [6:0] rx_message_counter,
  input  logic  [7:0] acceptance_code_0,
  input  logic  [7:0] acceptance_mask_0,
  input  logic  [7:0] acceptance_code_1,
  input  logic  [7:0] acceptance_code_2,
  input  logic  [7:0] acceptance_code_3,
  input  logic  [7:0] acceptance_mask_1,
  input  logic  [7:0] acceptance_mask_2,
  input  logic  [7:0] acceptance_mask_3,
  input  logic  [7:0] tx_data_0,
  input  logic  [7:0] tx_data_1,
  input  logic  [7:0] tx_data_2,
  input  logic  [7:0] tx_data_3,
  input  logic  [7:0] tx_data_4,
  input  logic  [7:0] tx_data_5,
  input  logic  [7:0] tx_data_6,
  input  logic  [7:0] tx_data_7,
  input  logic  [7:0] tx_data_8,
  input  logic  [7:0] tx_data_9,
  input  logic  [7:0] tx_data_10,
  input  logic  [7:0] tx_data_11,
  input  logic  [7:0] tx_data_12,
  output logic       tx,
  output logic       tx_next,
  output logic       bus_off_on,
  output logic       go_overload_frame,
  output logic       go_error_frame,
  output logic       go_tx,
  output logic       send_ack
);
logic         reset_mode_q;
logic   [5:0] bit_cnt;
logic   [3:0] data_len;
logic  [28:0] id;
logic   [2:0] bit_stuff_cnt;
logic   [2:0] bit_stuff_cnt_tx;
logic         tx_point_q;
logic         rx_idle;
logic         rx_id1;
logic         rx_rtr1;
logic         rx_ide;
logic         rx_id2;
logic         rx_rtr2;
logic         rx_r1;
logic         rx_r0;
logic         rx_dlc;
logic         rx_data;
logic         rx_crc;
logic         rx_crc_lim;
logic         rx_ack;
logic         rx_ack_lim;
logic         rx_eof;
logic         rx_inter;
logic         go_early_tx_latched;
logic         rtr1;
logic         ide;
logic         rtr2;
logic  [14:0] crc_in;
logic   [7:0] tmp_data;
logic   [7:0] tmp_fifo [0:7];
logic         write_data_to_tmp_fifo;
logic   [2:0] byte_cnt;
logic         bit_stuff_cnt_en;
logic         crc_enable;
logic   [2:0] eof_cnt;
logic   [2:0] passive_cnt;
logic         transmitting;
logic         error_frame;
logic         enable_error_cnt2;
logic   [2:0] error_cnt1;
logic   [2:0] error_cnt2;
logic   [2:0] delayed_dominant_cnt;
logic         enable_overload_cnt2;
logic         overload_frame;
logic         overload_frame_blocked;
logic   [1:0] overload_request_cnt;
logic   [2:0] overload_cnt1;
logic   [2:0] overload_cnt2;
logic         tx;
logic         crc_err;
logic         arbitration_lost;
logic         arbitration_lost_q;
logic         arbitration_field_d;
logic   [4:0] arbitration_lost_capture;
logic   [4:0] arbitration_cnt;
logic         arbitration_blocked;
logic         tx_q;
logic         need_to_tx;   
logic   [3:0] data_cnt;     
logic   [2:0] header_cnt;   
logic         wr_fifo;      
logic   [7:0] data_for_fifo;
logic   [5:0] tx_pointer;
logic         tx_bit;
logic         tx_state;
logic         tx_state_q;
logic         transmitter;
logic         finish_msg;
logic   [8:0] rx_err_cnt;
logic   [8:0] tx_err_cnt;
logic   [3:0] bus_free_cnt;
logic         bus_free_cnt_en;
logic         bus_free;
logic         waiting_for_bus_free;
logic         node_error_passive;
logic         node_bus_off;
logic         node_bus_off_q;
logic         ack_err_latched;
logic         bit_err_latched;
logic         stuff_err_latched;
logic         form_err_latched;
logic         rule3_exc1_1;
logic         rule3_exc1_2;
logic         suspend;
logic         susp_cnt_en;
logic   [2:0] susp_cnt;
logic         error_flag_over_latched;
logic   [7:0] error_capture_code;
logic   [7:6] error_capture_code_type;
logic         error_capture_code_blocked;
logic         tx_next;
logic         first_compare_bit;
logic   [4:0] error_capture_code_segment;
logic         error_capture_code_direction;
logic         bit_de_stuff;
logic         bit_de_stuff_tx;
logic         rule5;
logic         go_rx_idle;
logic         go_rx_id1;
logic         go_rx_rtr1;
logic         go_rx_ide;
logic         go_rx_id2;
logic         go_rx_rtr2;
logic         go_rx_r1;
logic         go_rx_r0;
logic         go_rx_dlc;
logic         go_rx_data;
logic         go_rx_crc;
logic         go_rx_crc_lim;
logic         go_rx_ack;
logic         go_rx_ack_lim;
logic         go_rx_eof;
logic         go_rx_inter;
logic         last_bit_of_inter;
logic         go_crc_enable;
logic         rst_crc_enable;
logic         bit_de_stuff_set;
logic         bit_de_stuff_reset;
logic         go_early_tx;
logic  [14:0] calculated_crc;
logic  [15:0] r_calculated_crc;
logic         remote_rq;
logic   [3:0] limited_data_len;
logic         form_err;
logic         error_frame_ended;
logic         overload_frame_ended;
logic         bit_err;
logic         ack_err;
logic         stuff_err;
logic         id_ok;                
logic         no_byte0;             
logic         no_byte1;             
logic   [2:0] header_len;
logic         storing_header;
logic   [3:0] limited_data_len_minus1;
logic         reset_wr_fifo;
logic         err;
logic         arbitration_field;
logic  [18:0] basic_chain;
logic  [63:0] basic_chain_data;
logic  [18:0] extended_chain_std;
logic  [38:0] extended_chain_ext;
logic  [63:0] extended_chain_data_std;
logic  [63:0] extended_chain_data_ext;
logic         rst_tx_pointer;
logic   [7:0] r_tx_data_0;
logic   [7:0] r_tx_data_1;
logic   [7:0] r_tx_data_2;
logic   [7:0] r_tx_data_3;
logic   [7:0] r_tx_data_4;
logic   [7:0] r_tx_data_5;
logic   [7:0] r_tx_data_6;
logic   [7:0] r_tx_data_7;
logic   [7:0] r_tx_data_8;
logic   [7:0] r_tx_data_9;
logic   [7:0] r_tx_data_10;
logic   [7:0] r_tx_data_11;
logic   [7:0] r_tx_data_12;
logic         send_ack;
logic         bit_err_exc1;
logic         bit_err_exc2;
logic         bit_err_exc3;
logic         bit_err_exc4;
logic         bit_err_exc5;
logic         bit_err_exc6;
logic         error_flag_over;
logic         overload_flag_over;
logic   [5:0] limited_tx_cnt_ext;
logic   [5:0] limited_tx_cnt_std;
assign go_rx_idle     =                   sample_point &  sampled_bit & last_bit_of_inter | bus_free & (~node_bus_off);
assign go_rx_id1      =                   sample_point &  (~sampled_bit) & (rx_idle | last_bit_of_inter);
assign go_rx_rtr1     = (~bit_de_stuff) & sample_point &  rx_id1  & (bit_cnt[3:0] == 4'd10);
assign go_rx_ide      = (~bit_de_stuff) & sample_point &  rx_rtr1;
assign go_rx_id2      = (~bit_de_stuff) & sample_point &  rx_ide  &   sampled_bit;
assign go_rx_rtr2     = (~bit_de_stuff) & sample_point &  rx_id2  & (bit_cnt[4:0] == 5'd17);
assign go_rx_r1       = (~bit_de_stuff) & sample_point &  rx_rtr2;
assign go_rx_r0       = (~bit_de_stuff) & sample_point & (rx_ide  & (~sampled_bit) | rx_r1);
assign go_rx_dlc      = (~bit_de_stuff) & sample_point &  rx_r0;
assign go_rx_data     = (~bit_de_stuff) & sample_point &  rx_dlc  & (bit_cnt[1:0] == 2'd3) &  (sampled_bit   |   (|data_len[2:0])) & (~remote_rq);
assign go_rx_crc      = (~bit_de_stuff) & sample_point & (rx_dlc  & (bit_cnt[1:0] == 2'd3) & ((~sampled_bit) & (~(|data_len[2:0])) | remote_rq) |
                                                          rx_data & (bit_cnt[5:0] == ((limited_data_len<<3) - 1'b1)));  
assign go_rx_crc_lim  = (~bit_de_stuff) & sample_point &  rx_crc  & (bit_cnt[3:0] == 4'd14);
assign go_rx_ack      = (~bit_de_stuff) & sample_point &  rx_crc_lim;
assign go_rx_ack_lim  =                   sample_point &  rx_ack;
assign go_rx_eof      =                   sample_point &  rx_ack_lim;
assign go_rx_inter    =                 ((sample_point &  rx_eof  & (eof_cnt == 3'd6)) | error_frame_ended | overload_frame_ended) & (~overload_request);
assign go_error_frame = (form_err | stuff_err | bit_err | ack_err | (crc_err & go_rx_eof));
assign error_frame_ended = (error_cnt2 == 3'd7) & tx_point;
assign overload_frame_ended = (overload_cnt2 == 3'd7) & tx_point;
assign go_overload_frame = (     sample_point & ((~sampled_bit) | overload_request) & (rx_eof & (~transmitter) & (eof_cnt == 3'd6) | error_frame_ended | overload_frame_ended) | 
                                 sample_point & (~sampled_bit) & rx_inter & (bit_cnt[1:0] < 2'd2)                                                            |
                                 sample_point & (~sampled_bit) & ((error_cnt2 == 3'd7) | (overload_cnt2 == 3'd7))
                           )  & (~overload_frame_blocked)  ;
assign go_crc_enable  = hard_sync | go_tx;
assign rst_crc_enable = go_rx_crc;
assign bit_de_stuff_set   = go_rx_id1 & (~go_error_frame);
assign bit_de_stuff_reset = go_rx_ack | go_error_frame | go_overload_frame;
assign remote_rq = ((~ide) & rtr1) | (ide & rtr2);
assign limited_data_len = (data_len < 4'h8)? data_len : 4'h8;
assign ack_err = rx_ack & sample_point & sampled_bit & tx_state & (~self_test_mode);
assign bit_err = (tx_state | error_frame | overload_frame | rx_ack) & sample_point & (tx != sampled_bit) & (~bit_err_exc1) & (~bit_err_exc2) & (~bit_err_exc3) & (~bit_err_exc4) & (~bit_err_exc5) & (~bit_err_exc6) & (~reset_mode);
assign bit_err_exc1 = tx_state & arbitration_field & tx;
assign bit_err_exc2 = rx_ack & tx;
assign bit_err_exc3 = error_frame & node_error_passive & (error_cnt1 < 3'd7);
assign bit_err_exc4 = (error_frame & (error_cnt1 == 3'd7) & (~enable_error_cnt2)) | (overload_frame & (overload_cnt1 == 3'd7) & (~enable_overload_cnt2));
assign bit_err_exc5 = (error_frame & (error_cnt2 == 3'd7)) | (overload_frame & (overload_cnt2 == 3'd7));
assign bit_err_exc6 = (eof_cnt == 3'd6) & rx_eof & (~transmitter); 
assign arbitration_field = rx_id1 | rx_rtr1 | rx_ide | rx_id2 | rx_rtr2;
assign last_bit_of_inter = rx_inter & (bit_cnt[1:0] == 2'd2);
assign not_first_bit_of_inter = rx_inter & (bit_cnt[1:0] != 2'd0);
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_idle <= 1'b0;
  else if (go_rx_id1 | go_error_frame)
    rx_idle <= 1'b0;
  else if (go_rx_idle)
    rx_idle <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_id1 <= 1'b0;
  else if (go_rx_rtr1 | go_error_frame)
    rx_id1 <= 1'b0;
  else if (go_rx_id1)
    rx_id1 <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_rtr1 <= 1'b0;
  else if (go_rx_ide | go_error_frame)
    rx_rtr1 <= 1'b0;
  else if (go_rx_rtr1)
    rx_rtr1 <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_ide <= 1'b0;
  else if (go_rx_r0 | go_rx_id2 | go_error_frame)
    rx_ide <= 1'b0;
  else if (go_rx_ide)
    rx_ide <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_id2 <= 1'b0;
  else if (go_rx_rtr2 | go_error_frame)
    rx_id2 <= 1'b0;
  else if (go_rx_id2)
    rx_id2 <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_rtr2 <= 1'b0;
  else if (go_rx_r1 | go_error_frame)
    rx_rtr2 <= 1'b0;
  else if (go_rx_rtr2)
    rx_rtr2 <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_r1 <= 1'b0;
  else if (go_rx_r0 | go_error_frame)
    rx_r1 <= 1'b0;
  else if (go_rx_r1)
    rx_r1 <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_r0 <= 1'b0;
  else if (go_rx_dlc | go_error_frame)
    rx_r0 <= 1'b0;
  else if (go_rx_r0)
    rx_r0 <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_dlc <= 1'b0;
  else if (go_rx_data | go_rx_crc | go_error_frame)
    rx_dlc <= 1'b0;
  else if (go_rx_dlc)
    rx_dlc <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_data <= 1'b0;
  else if (go_rx_crc | go_error_frame)
    rx_data <= 1'b0;
  else if (go_rx_data)
    rx_data <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_crc <= 1'b0;
  else if (go_rx_crc_lim | go_error_frame)
    rx_crc <= 1'b0;
  else if (go_rx_crc)
    rx_crc <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_crc_lim <= 1'b0;
  else if (go_rx_ack | go_error_frame)
    rx_crc_lim <= 1'b0;
  else if (go_rx_crc_lim)
    rx_crc_lim <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_ack <= 1'b0;
  else if (go_rx_ack_lim | go_error_frame)
    rx_ack <= 1'b0;
  else if (go_rx_ack)
    rx_ack <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_ack_lim <= 1'b0;
  else if (go_rx_eof | go_error_frame)
    rx_ack_lim <= 1'b0;
  else if (go_rx_ack_lim)
    rx_ack_lim <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_eof <= 1'b0;
  else if (go_rx_inter | go_error_frame | go_overload_frame)
    rx_eof <= 1'b0;
  else if (go_rx_eof)
    rx_eof <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_inter <= 1'b0;
  else if (go_rx_idle | go_rx_id1 | go_overload_frame | go_error_frame)
    rx_inter <= 1'b0;
  else if (go_rx_inter)
    rx_inter <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    id <= 29'h0;
  else if (sample_point & (rx_id1 | rx_id2) & (~bit_de_stuff))
    id <= {id[27:0], sampled_bit};
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rtr1 <= 1'b0;
  else if (sample_point & rx_rtr1 & (~bit_de_stuff))
    rtr1 <= sampled_bit;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rtr2 <= 1'b0;
  else if (sample_point & rx_rtr2 & (~bit_de_stuff))
    rtr2 <= sampled_bit;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    ide <= 1'b0;
  else if (sample_point & rx_ide & (~bit_de_stuff))
    ide <= sampled_bit;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    data_len <= 4'b0;
  else if (sample_point & rx_dlc & (~bit_de_stuff))
    data_len <= {data_len[2:0], sampled_bit};
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    tmp_data <= 8'h0;
  else if (sample_point & rx_data & (~bit_de_stuff))
    tmp_data <= {tmp_data[6:0], sampled_bit};
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    write_data_to_tmp_fifo <= 1'b0;
  else if (sample_point & rx_data & (~bit_de_stuff) & (&bit_cnt[2:0]))
    write_data_to_tmp_fifo <= 1'b1;
  else
    write_data_to_tmp_fifo <= 1'b0;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    byte_cnt <= 3'h0;
  else if (write_data_to_tmp_fifo)
    byte_cnt <= byte_cnt + 1'b1;
  else if (sample_point & go_rx_crc_lim)
    byte_cnt <= 3'h0;
end
always @ (posedge clk) begin
  if (write_data_to_tmp_fifo)
    tmp_fifo[byte_cnt] <= tmp_data;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    crc_in <= 15'h0;
  else if (sample_point & rx_crc & (~bit_de_stuff))
    crc_in <= {crc_in[13:0], sampled_bit};
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    bit_cnt <= 6'd0;
  else if (go_rx_id1 | go_rx_id2 | go_rx_dlc | go_rx_data | go_rx_crc | 
           go_rx_ack | go_rx_eof | go_rx_inter | go_error_frame | go_overload_frame)
    bit_cnt <= 6'd0;
  else if (sample_point & (~bit_de_stuff))
    bit_cnt <= bit_cnt + 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    eof_cnt <= 3'd0;
  else if (sample_point) begin
      if (go_rx_inter | go_error_frame | go_overload_frame)
        eof_cnt <= 3'd0;
      else if (rx_eof)
        eof_cnt <= eof_cnt + 1'b1;
    end
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    bit_stuff_cnt_en <= 1'b0;
  else if (bit_de_stuff_set)
    bit_stuff_cnt_en <= 1'b1;
  else if (bit_de_stuff_reset)
    bit_stuff_cnt_en <= 1'b0;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    bit_stuff_cnt <= 3'h1;
  else if (bit_de_stuff_reset)
    bit_stuff_cnt <= 3'h1;
  else if (sample_point & bit_stuff_cnt_en) begin
      if (bit_stuff_cnt == 3'h5)
        bit_stuff_cnt <= 3'h1;
      else if (sampled_bit == sampled_bit_q)
        bit_stuff_cnt <= bit_stuff_cnt + 1'b1;
      else
        bit_stuff_cnt <= 3'h1;
    end
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    bit_stuff_cnt_tx <= 3'h1;
  else if (reset_mode || bit_de_stuff_reset)
    bit_stuff_cnt_tx <= 3'h1;
  else if (tx_point_q & bit_stuff_cnt_en) begin
      if (bit_stuff_cnt_tx == 3'h5)
        bit_stuff_cnt_tx <= 3'h1;
      else if (tx == tx_q)
        bit_stuff_cnt_tx <= bit_stuff_cnt_tx + 1'b1;
      else
        bit_stuff_cnt_tx <= 3'h1;
    end
end
assign bit_de_stuff = bit_stuff_cnt == 3'h5;
assign bit_de_stuff_tx = bit_stuff_cnt_tx == 3'h5;
assign stuff_err = sample_point & bit_stuff_cnt_en & bit_de_stuff & (sampled_bit == sampled_bit_q);
always @ (posedge clk or posedge rst) begin
  if (rst) begin
      reset_mode_q <= 1'b0;
      node_bus_off_q <= 1'b0;
    end
  else begin
      reset_mode_q <= reset_mode;
      node_bus_off_q <= node_bus_off;
    end
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    crc_enable <= 1'b0;
  else if (rst_crc_enable)
    crc_enable <= 1'b0;
  else if (go_crc_enable)
    crc_enable <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    crc_err <= 1'b0;
  else if (reset_mode | error_frame_ended)
    crc_err <= 1'b0;
  else if (go_rx_ack)
    crc_err <= crc_in != calculated_crc;
end
assign form_err = sample_point & ( ((~bit_de_stuff) & rx_crc_lim & (~sampled_bit)                  ) |
                                   (                  rx_ack_lim & (~sampled_bit)                  ) |
                                   ((eof_cnt < 3'd6)& rx_eof     & (~sampled_bit) & (~transmitter) ) |
                                   (                & rx_eof     & (~sampled_bit) &   transmitter  )
                                 );
always @ (posedge clk or posedge rst) begin
  if (rst)
    ack_err_latched <= 1'b0;
  else if (reset_mode | error_frame_ended | go_overload_frame)
    ack_err_latched <= 1'b0;
  else if (ack_err)
    ack_err_latched <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    bit_err_latched <= 1'b0;
  else if (reset_mode | error_frame_ended | go_overload_frame)
    bit_err_latched <= 1'b0;
  else if (bit_err)
    bit_err_latched <= 1'b1;
end
assign rule5 = bit_err &  ( (~node_error_passive) & error_frame    & (error_cnt1    < 3'd7)
                            | 
                                                    overload_frame & (overload_cnt1 < 3'd7)
                          );
always @ (posedge clk or posedge rst) begin
  if (rst)
    rule3_exc1_1 <= 1'b0;
  else if (error_flag_over | rule3_exc1_2)
    rule3_exc1_1 <= 1'b0;
  else if (transmitter & node_error_passive & ack_err)
    rule3_exc1_1 <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rule3_exc1_2 <= 1'b0;
  else if (go_error_frame | rule3_exc1_2)
    rule3_exc1_2 <= 1'b0;
  else if (rule3_exc1_1 & (error_cnt1 < 3'd7) & sample_point & (~sampled_bit))
    rule3_exc1_2 <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    stuff_err_latched <= 1'b0;
  else if (reset_mode | error_frame_ended | go_overload_frame)
    stuff_err_latched <= 1'b0;
  else if (stuff_err)
    stuff_err_latched <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    form_err_latched <= 1'b0;
  else if (reset_mode | error_frame_ended | go_overload_frame)
    form_err_latched <= 1'b0;
  else if (form_err)
    form_err_latched <= 1'b1;
end
can_crc i_can_crc_rx 
(
  .clk(clk),
  .data(sampled_bit),
  .enable(crc_enable & sample_point & (~bit_de_stuff)),
  .initialize(go_crc_enable),
  .crc(calculated_crc)
);
assign no_byte0 = rtr1 | (data_len<4'h1);
assign no_byte1 = rtr1 | (data_len<4'h2);
can_acf i_can_acf
(
  .clk(clk),
  .rst(rst),
  .id(id),
  .reset_mode(reset_mode),
  .acceptance_filter_mode(acceptance_filter_mode),
  .extended_mode(extended_mode),
  .acceptance_code_0(acceptance_code_0),
  .acceptance_mask_0(acceptance_mask_0),
  .acceptance_code_1(acceptance_code_1),
  .acceptance_code_2(acceptance_code_2),
  .acceptance_code_3(acceptance_code_3),
  .acceptance_mask_1(acceptance_mask_1),
  .acceptance_mask_2(acceptance_mask_2),
  .acceptance_mask_3(acceptance_mask_3),
  .go_rx_crc_lim(go_rx_crc_lim),
  .go_rx_inter(go_rx_inter),
  .go_error_frame(go_error_frame),
  .data0(tmp_fifo[0]),
  .data1(tmp_fifo[1]),
  .rtr1(rtr1),
  .rtr2(rtr2),
  .ide(ide),
  .no_byte0(no_byte0),
  .no_byte1(no_byte1),
  .id_ok(id_ok)
);
assign header_len[2:0] = extended_mode ? (ide? (3'h5) : (3'h3)) : 3'h2;
assign storing_header = header_cnt < header_len;
assign limited_data_len_minus1[3:0] = remote_rq? 4'hf : ((data_len < 4'h8)? (data_len -1'b1) : 4'h7);   
assign reset_wr_fifo = (data_cnt == (limited_data_len_minus1 + {1'b0, header_len})) || reset_mode;
assign err = form_err | stuff_err | bit_err | ack_err | form_err_latched | stuff_err_latched | bit_err_latched | ack_err_latched | crc_err;
always @ (posedge clk or posedge rst) begin
  if (rst)
    wr_fifo <= 1'b0;
  else if (reset_wr_fifo)
    wr_fifo <= 1'b0;
  else if (go_rx_inter & id_ok & (~error_frame_ended) & ((~tx_state) | self_rx_request))
    wr_fifo <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    header_cnt <= 3'h0;
  else if (reset_wr_fifo)
    header_cnt <= 3'h0;
  else if (wr_fifo & storing_header)
    header_cnt <= header_cnt + 1'h1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    data_cnt <= 4'h0;
  else if (reset_wr_fifo)
    data_cnt <= 4'h0;
  else if (wr_fifo)
    data_cnt <= data_cnt + 4'h1;
end
always @ (extended_mode or ide or data_cnt or header_cnt or  header_len or 
          storing_header or id or rtr1 or rtr2 or data_len or
          tmp_fifo[0] or tmp_fifo[2] or tmp_fifo[4] or tmp_fifo[6] or 
          tmp_fifo[1] or tmp_fifo[3] or tmp_fifo[5] or tmp_fifo[7]) begin
  casex ({storing_header, extended_mode, ide, header_cnt})  
    6'b1_1_1_000  : data_for_fifo = {1'b1, rtr2, 2'h0, data_len};  
    6'b1_1_1_001  : data_for_fifo = id[28:21];                     
    6'b1_1_1_010  : data_for_fifo = id[20:13];                     
    6'b1_1_1_011  : data_for_fifo = id[12:5];                      
    6'b1_1_1_100  : data_for_fifo = {id[4:0], 3'h0};               
    6'b1_1_0_000  : data_for_fifo = {1'b0, rtr1, 2'h0, data_len};  
    6'b1_1_0_001  : data_for_fifo = id[10:3];                      
    6'b1_1_0_010  : data_for_fifo = {id[2:0], rtr1, 4'h0};         
    6'b1_0_x_000  : data_for_fifo = id[10:3];                      
    6'b1_0_x_001  : data_for_fifo = {id[2:0], rtr1, data_len};     
    default       : data_for_fifo = tmp_fifo[data_cnt - {1'b0, header_len}]; 
  endcase
end
can_fifo i_can_fifo
( 
  .clk(clk),
  .rst(rst),
  .wr(wr_fifo),
  .data_in(data_for_fifo),
  .addr(addr[5:0]),
  .data_out(data_out),
  .fifo_selected(fifo_selected),
  .reset_mode(reset_mode),
  .release_buffer(release_buffer),
  .extended_mode(extended_mode),
  .overrun(overrun),
  .info_empty(info_empty),
  .info_cnt(rx_message_counter)
);
always @ (posedge clk or posedge rst) begin
  if (rst)
    error_frame <= 1'b0;
  else if (set_reset_mode || error_frame_ended || go_overload_frame)
    error_frame <= 1'b0;
  else if (go_error_frame)
    error_frame <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    error_cnt1 <= 3'd0;
  else if (error_frame_ended | go_error_frame | go_overload_frame)
    error_cnt1 <= 3'd0;
  else if (error_frame & tx_point & (error_cnt1 < 3'd7))
    error_cnt1 <= error_cnt1 + 1'b1;
end
assign error_flag_over = ((~node_error_passive) & sample_point & (error_cnt1 == 3'd7) | node_error_passive  & sample_point & (passive_cnt == 3'h6)) & (~enable_error_cnt2);
always @ (posedge clk or posedge rst) begin
  if (rst)
    error_flag_over_latched <= 1'b0;
  else if (error_frame_ended | go_error_frame | go_overload_frame)
    error_flag_over_latched <= 1'b0;
  else if (error_flag_over)
    error_flag_over_latched <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    enable_error_cnt2 <= 1'b0;
  else if (error_frame_ended | go_error_frame | go_overload_frame)
    enable_error_cnt2 <= 1'b0;
  else if (error_frame & (error_flag_over & sampled_bit))
    enable_error_cnt2 <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    error_cnt2 <= 3'd0;
  else if (error_frame_ended | go_error_frame | go_overload_frame)
    error_cnt2 <= 3'd0;
  else if (enable_error_cnt2 & tx_point)
    error_cnt2 <= error_cnt2 + 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    delayed_dominant_cnt <= 3'h0;
  else if (enable_error_cnt2 | go_error_frame | enable_overload_cnt2 | go_overload_frame)
    delayed_dominant_cnt <= 3'h0;
  else if (sample_point & (~sampled_bit) & ((error_cnt1 == 3'd7) | (overload_cnt1 == 3'd7)))
    delayed_dominant_cnt <= delayed_dominant_cnt + 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    passive_cnt <= 3'h1;
  else if (error_frame_ended | go_error_frame | go_overload_frame | first_compare_bit)
    passive_cnt <= 3'h1;
  else if (sample_point & (passive_cnt < 3'h6)) begin
      if (error_frame & (~enable_error_cnt2) & (sampled_bit == sampled_bit_q))
        passive_cnt <= passive_cnt + 1'b1;
      else
        passive_cnt <= 3'h1;
    end
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    first_compare_bit <= 1'b0;
  else if (go_error_frame)
    first_compare_bit <= 1'b1;
  else if (sample_point)
    first_compare_bit <= 1'b0;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    overload_frame <= 1'b0;
  else if (overload_frame_ended | go_error_frame)
    overload_frame <= 1'b0;
  else if (go_overload_frame)
    overload_frame <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    overload_cnt1 <= 3'd0;
  else if (overload_frame_ended | go_error_frame | go_overload_frame)
    overload_cnt1 <= 3'd0;
  else if (overload_frame & tx_point & (overload_cnt1 < 3'd7))
    overload_cnt1 <= overload_cnt1 + 1'b1;
end
assign overload_flag_over = sample_point & (overload_cnt1 == 3'd7) & (~enable_overload_cnt2);
always @ (posedge clk or posedge rst) begin
  if (rst)
    enable_overload_cnt2 <= 1'b0;
  else if (overload_frame_ended | go_error_frame | go_overload_frame)
    enable_overload_cnt2 <= 1'b0;
  else if (overload_frame & (overload_flag_over & sampled_bit))
    enable_overload_cnt2 <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    overload_cnt2 <= 3'd0;
  else if (overload_frame_ended | go_error_frame | go_overload_frame)
    overload_cnt2 <= 3'd0;
  else if (enable_overload_cnt2 & tx_point)
    overload_cnt2 <= overload_cnt2 + 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    overload_request_cnt <= 2'b0;
  else if (go_error_frame | go_rx_id1)
    overload_request_cnt <= 2'b0;
  else if (overload_request & overload_frame)
    overload_request_cnt <= overload_request_cnt + 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    overload_frame_blocked <= 1'b0;
  else if (go_error_frame | go_rx_id1)
    overload_frame_blocked <= 1'b0;
  else if (overload_request & overload_frame & overload_request_cnt == 2'h2)   
    overload_frame_blocked <= 1'b1;
end
assign send_ack = (~tx_state) & rx_ack & (~err) & (~listen_only_mode);
always @ (reset_mode or node_bus_off or tx_state or go_tx or bit_de_stuff_tx or tx_bit or tx_q or
          send_ack or go_overload_frame or overload_frame or overload_cnt1 or
          go_error_frame or error_frame or error_cnt1 or node_error_passive) begin
  if (reset_mode | node_bus_off)                                                
    tx_next = 1'b1;
  else begin
      if (go_error_frame | error_frame)                                         
          if (error_cnt1 < 3'd6) begin
              if (node_error_passive)
                tx_next = 1'b1;
              else
                tx_next = 1'b0;
            end
          else
            tx_next = 1'b1;
        end
      else if (go_overload_frame | overload_frame)                              
          if (overload_cnt1 < 3'd6)
            tx_next = 1'b0;
          else
            tx_next = 1'b1;
        end
      else if (go_tx | tx_state)                                                        
        tx_next = ((~bit_de_stuff_tx) & tx_bit) | (bit_de_stuff_tx & (~tx_q));
      else if (send_ack)                                                        
        tx_next = 1'b0;
      else
        tx_next = 1'b1;
    end
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    tx <= 1'b1;
  else if (reset_mode)
    tx <= 1'b1;
  else if (tx_point)
    tx <= tx_next;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    tx_q <= 1'b0;
  else if (reset_mode)
    tx_q <= 1'b0;
  else if (tx_point)
    tx_q <= tx & (~go_early_tx_latched);
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    tx_point_q <= 1'b0;
  else if (reset_mode)
    tx_point_q <= 1'b0;
  else
    tx_point_q <= tx_point;
end
can_ibo i_ibo_tx_data_0  (.di(tx_data_0),  .do(r_tx_data_0));
can_ibo i_ibo_tx_data_1  (.di(tx_data_1),  .do(r_tx_data_1));
can_ibo i_ibo_tx_data_2  (.di(tx_data_2),  .do(r_tx_data_2));
can_ibo i_ibo_tx_data_3  (.di(tx_data_3),  .do(r_tx_data_3));
can_ibo i_ibo_tx_data_4  (.di(tx_data_4),  .do(r_tx_data_4));
can_ibo i_ibo_tx_data_5  (.di(tx_data_5),  .do(r_tx_data_5));
can_ibo i_ibo_tx_data_6  (.di(tx_data_6),  .do(r_tx_data_6));
can_ibo i_ibo_tx_data_7  (.di(tx_data_7),  .do(r_tx_data_7));
can_ibo i_ibo_tx_data_8  (.di(tx_data_8),  .do(r_tx_data_8));
can_ibo i_ibo_tx_data_9  (.di(tx_data_9),  .do(r_tx_data_9));
can_ibo i_ibo_tx_data_10 (.di(tx_data_10), .do(r_tx_data_10));
can_ibo i_ibo_tx_data_11 (.di(tx_data_11), .do(r_tx_data_11));
can_ibo i_ibo_tx_data_12 (.di(tx_data_12), .do(r_tx_data_12));
can_ibo i_calculated_crc0 (.di(calculated_crc[14:7]), .do(r_calculated_crc[7:0]));
can_ibo i_calculated_crc1 (.di({calculated_crc[6:0], 1'b0}), .do(r_calculated_crc[15:8]));
assign basic_chain = {r_tx_data_1[7:4], 2'h0, r_tx_data_1[3:0], r_tx_data_0[7:0], 1'b0};
assign basic_chain_data = {r_tx_data_9, r_tx_data_8, r_tx_data_7, r_tx_data_6, r_tx_data_5, r_tx_data_4, r_tx_data_3, r_tx_data_2};
assign extended_chain_std = {r_tx_data_0[7:4], 2'h0, r_tx_data_0[1], r_tx_data_2[2:0], r_tx_data_1[7:0], 1'b0};
assign extended_chain_ext = {r_tx_data_0[7:4], 2'h0, r_tx_data_0[1], r_tx_data_4[4:0], r_tx_data_3[7:0], r_tx_data_2[7:3], 1'b1, 1'b1, r_tx_data_2[2:0], r_tx_data_1[7:0], 1'b0};
assign extended_chain_data_std = {r_tx_data_10, r_tx_data_9, r_tx_data_8, r_tx_data_7, r_tx_data_6, r_tx_data_5, r_tx_data_4, r_tx_data_3};
assign extended_chain_data_ext = {r_tx_data_12, r_tx_data_11, r_tx_data_10, r_tx_data_9, r_tx_data_8, r_tx_data_7, r_tx_data_6, r_tx_data_5};
always @ (extended_mode or rx_data or tx_pointer or extended_chain_data_std or extended_chain_data_ext or rx_crc or r_calculated_crc or
          r_tx_data_0   or extended_chain_ext or extended_chain_std or basic_chain_data or basic_chain or
          finish_msg) begin
  if (extended_mode) begin
      if (rx_data)  
        if (r_tx_data_0[0])    
          tx_bit = extended_chain_data_ext[tx_pointer];
        else
          tx_bit = extended_chain_data_std[tx_pointer];
      else if (rx_crc)
        tx_bit = r_calculated_crc[tx_pointer];
      else if (finish_msg)
        tx_bit = 1'b1;
      else begin
          if (r_tx_data_0[0])    
            tx_bit = extended_chain_ext[tx_pointer];
          else
            tx_bit = extended_chain_std[tx_pointer];
        end
    end
  else  
      if (rx_data)  
        tx_bit = basic_chain_data[tx_pointer];
      else if (rx_crc)
        tx_bit = r_calculated_crc[tx_pointer];
      else if (finish_msg)
        tx_bit = 1'b1;
      else
        tx_bit = basic_chain[tx_pointer];
    end
end
assign limited_tx_cnt_ext = tx_data_0[3] ? 6'h3f : ((tx_data_0[2:0] <<3) - 1'b1);
assign limited_tx_cnt_std = tx_data_1[3] ? 6'h3f : ((tx_data_1[2:0] <<3) - 1'b1);
assign rst_tx_pointer = ((~bit_de_stuff_tx) & tx_point & (~rx_data) &   extended_mode  &   r_tx_data_0[0]   & tx_pointer == 6'd38             ) |   
                        ((~bit_de_stuff_tx) & tx_point & (~rx_data) &   extended_mode  & (~r_tx_data_0[0])  & tx_pointer == 6'd18             ) |   
                        ((~bit_de_stuff_tx) & tx_point & (~rx_data) & (~extended_mode)                      & tx_pointer == 6'd18             ) |   
                        ((~bit_de_stuff_tx) & tx_point &   rx_data  &   extended_mode                       & tx_pointer == limited_tx_cnt_ext) |   
                        ((~bit_de_stuff_tx) & tx_point &   rx_data  & (~extended_mode)                      & tx_pointer == limited_tx_cnt_std) |   
                        (                     tx_point &   rx_crc_lim                                                                         ) |   
                        (go_rx_idle                                                                                                           ) |   
                        (reset_mode                                                                                                           ) |
                        (overload_frame                                                                                                       ) |
                        (error_frame                                                                                                          ) ;
always @ (posedge clk or posedge rst) begin
  if (rst)
    tx_pointer <= 6'h0;
  else if (rst_tx_pointer)
    tx_pointer <= 6'h0;
  else if (go_early_tx | (tx_point & (tx_state | go_tx) & (~bit_de_stuff_tx)))
    tx_pointer <= tx_pointer + 1'b1;
end
assign tx_successful = transmitter & go_rx_inter & (~go_error_frame) & (~error_frame_ended) & (~overload_frame_ended) & (~arbitration_lost);
always @ (posedge clk or posedge rst) begin
  if (rst)
    need_to_tx <= 1'b0;
  else if (tx_successful | reset_mode | (abort_tx & (~transmitting)) | ((~tx_state) & tx_state_q & single_shot_transmission))
    need_to_tx <= 1'h0;
  else if (tx_request & sample_point)
    need_to_tx <= 1'b1;
end
assign go_early_tx = (~listen_only_mode) & need_to_tx & (~tx_state) & (~suspend | (susp_cnt == 3'h7)) & sample_point & (~sampled_bit) & (rx_idle | last_bit_of_inter);
assign go_tx       = (~listen_only_mode) & need_to_tx & (~tx_state) & (~suspend | (sample_point & (susp_cnt == 3'h7))) & (go_early_tx | rx_idle);
always @ (posedge clk or posedge rst) begin
  if (rst)
    go_early_tx_latched <= 1'b0;
  else if (reset_mode || tx_point)
    go_early_tx_latched <= 1'b0;
  else if (go_early_tx)
    go_early_tx_latched <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    tx_state <= 1'b0;
  else if (reset_mode | go_rx_inter | error_frame | arbitration_lost)
    tx_state <= 1'b0;
  else if (go_tx)
    tx_state <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    tx_state_q <= 1'b0;
  else if (reset_mode)
    tx_state_q <= 1'b0;
  else
    tx_state_q <= tx_state;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    transmitter <= 1'b0;
  else if (go_tx)
    transmitter <= 1'b1;
  else if (reset_mode | go_rx_idle | suspend & go_rx_id1)
    transmitter <= 1'b0;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    transmitting <= 1'b0;
  else if (go_error_frame | go_overload_frame | go_tx | send_ack)
    transmitting <= 1'b1;
  else if (reset_mode | go_rx_idle | (go_rx_id1 & (~tx_state)) | (arbitration_lost & tx_state))
    transmitting <= 1'b0;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    suspend <= 1'b0;
  else if (reset_mode | (sample_point & (susp_cnt == 3'h7)))
    suspend <= 1'b0;
  else if (not_first_bit_of_inter & transmitter & node_error_passive)
    suspend <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    susp_cnt_en <= 1'b0;
  else if (reset_mode | (sample_point & (susp_cnt == 3'h7)))
    susp_cnt_en <= 1'b0;
  else if (suspend & sample_point & last_bit_of_inter)
    susp_cnt_en <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    susp_cnt <= 3'h0;
  else if (reset_mode | (sample_point & (susp_cnt == 3'h7)))
    susp_cnt <= 3'h0;
  else if (susp_cnt_en & sample_point)
    susp_cnt <= susp_cnt + 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    finish_msg <= 1'b0;
  else if (go_rx_idle | go_rx_id1 | error_frame | reset_mode)
    finish_msg <= 1'b0;
  else if (go_rx_crc_lim)
    finish_msg <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    arbitration_lost <= 1'b0;
  else if (go_rx_idle | error_frame_ended)
    arbitration_lost <= 1'b0;
  else if (transmitter & sample_point & tx & arbitration_field & ~sampled_bit)
    arbitration_lost <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    arbitration_lost_q <= 1'b0;
  else
    arbitration_lost_q <= arbitration_lost;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    arbitration_field_d <= 1'b0;
  else if (sample_point)
    arbitration_field_d <= arbitration_field;
end
assign set_arbitration_lost_irq = arbitration_lost & (~arbitration_lost_q) & (~arbitration_blocked);
always @ (posedge clk or posedge rst) begin
  if (rst)
    arbitration_cnt <= 5'h0;
  else if (sample_point && !bit_de_stuff)
    if (arbitration_field_d)
      arbitration_cnt <= arbitration_cnt + 1'b1;
    else
      arbitration_cnt <= 5'h0;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    arbitration_lost_capture <= 5'h0;
  else if (set_arbitration_lost_irq)
    arbitration_lost_capture <= arbitration_cnt;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    arbitration_blocked <= 1'b0;
  else if (read_arbitration_lost_capture_reg)
    arbitration_blocked <= 1'b0;
  else if (set_arbitration_lost_irq)
    arbitration_blocked <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    rx_err_cnt <= 9'h0;
  else if (we_rx_err_cnt & (~node_bus_off))
    rx_err_cnt <= {1'b0, data_in};
  else if (set_reset_mode)
    rx_err_cnt <= 9'h0;
  else begin
      if ((~listen_only_mode) & (~transmitter | arbitration_lost)) begin
          if (go_rx_ack_lim & (~go_error_frame) & (~crc_err) & (rx_err_cnt > 9'h0)) begin
              if (rx_err_cnt > 9'd127)
                rx_err_cnt <= 9'd127;
              else
                rx_err_cnt <= rx_err_cnt - 1'b1;
            end
          else if (rx_err_cnt < 9'd128) begin
              if (go_error_frame & (~rule5))                                                                                          
                rx_err_cnt <= rx_err_cnt + 1'b1;
              else if ( (error_flag_over & (~error_flag_over_latched) & sample_point & (~sampled_bit) & (error_cnt1 == 3'd7)     ) |  
                        (go_error_frame & rule5                                                                                  ) |  
                        (sample_point & (~sampled_bit) & (delayed_dominant_cnt == 3'h7)                            )                  
                      )
                rx_err_cnt <= rx_err_cnt + 4'h8;
            end
        end
    end
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    tx_err_cnt <= 9'h0;
  else if (we_tx_err_cnt)
    tx_err_cnt <= {1'b0, data_in};
  else begin
      if (set_reset_mode)
        tx_err_cnt <= 9'd128;
      else if ((tx_err_cnt > 9'd0) & (tx_successful | bus_free))
        tx_err_cnt <= tx_err_cnt - 1'h1;
      else if (transmitter & (~arbitration_lost)) begin
          if ( (sample_point & (~sampled_bit) & (delayed_dominant_cnt == 3'h7)                                          ) |       
               (go_error_frame & rule5                                                                                  ) |       
               (go_error_frame & (~(transmitter & node_error_passive & ack_err)) & (~(transmitter & stuff_err & 
                arbitration_field & sample_point & tx & (~sampled_bit)))                                                ) |       
               (error_frame & rule3_exc1_2                                                                              )         
             )
            tx_err_cnt <= tx_err_cnt + 4'h8;
        end
    end
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    node_error_passive <= 1'b0;
  else if ((rx_err_cnt < 128) & (tx_err_cnt < 9'd128))
    node_error_passive <= 1'b0;
  else if (((rx_err_cnt >= 128) | (tx_err_cnt >= 9'd128)) & (error_frame_ended | go_error_frame | (~reset_mode) & reset_mode_q) & (~node_bus_off))
    node_error_passive <= 1'b1;
end
assign node_error_active = ~(node_error_passive | node_bus_off);
always @ (posedge clk or posedge rst) begin
  if (rst)
    node_bus_off <= 1'b0;
  else if ((rx_err_cnt == 9'h0) & (tx_err_cnt == 9'd0) & (~reset_mode) | (we_tx_err_cnt & (data_in < 8'd255)))
    node_bus_off <= 1'b0;
  else if ((tx_err_cnt >= 9'd256) | (we_tx_err_cnt & (data_in == 8'd255)))
    node_bus_off <= 1'b1;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    bus_free_cnt <= 4'h0;
  else if (sample_point) begin
      if (sampled_bit & bus_free_cnt_en & (bus_free_cnt < 4'd10))
        bus_free_cnt <= bus_free_cnt + 1'b1;
      else
        bus_free_cnt <= 4'h0;
    end
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    bus_free_cnt_en <= 1'b0;
  else if ((~reset_mode) & reset_mode_q | node_bus_off_q & (~reset_mode))
    bus_free_cnt_en <= 1'b1;
  else if (sample_point & sampled_bit & (bus_free_cnt==4'd10) & (~node_bus_off))
    bus_free_cnt_en <= 1'b0;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    bus_free <= 1'b0;
  else if (sample_point & sampled_bit & (bus_free_cnt==4'd10) && waiting_for_bus_free)
    bus_free <= 1'b1;
  else
    bus_free <= 1'b0;
end
always @ (posedge clk or posedge rst) begin
  if (rst)
    waiting_for_bus_free <= 1'b1;
  else if (bus_free & (~node_bus_off))
    waiting_for_bus_free <= 1'b0;
  else if (node_bus_off_q & (~reset_mode))
    waiting_for_bus_free <= 1'b1;
end
assign bus_off_on = ~node_bus_off;
assign set_reset_mode = node_bus_off & (~node_bus_off_q);
assign error_status = extended_mode? ((rx_err_cnt >= error_warning_limit) | (tx_err_cnt >= error_warning_limit))    :
                                     ((rx_err_cnt >= 9'd96) | (tx_err_cnt >= 9'd96))                                ;
assign transmit_status = transmitting  || (extended_mode && waiting_for_bus_free);
assign receive_status  = extended_mode ? (waiting_for_bus_free || (!rx_idle) && (!transmitting)) : 
                                         ((!waiting_for_bus_free) && (!rx_idle) && (!transmitting));
always @ (posedge clk or posedge rst) begin
  if (rst)
    error_capture_code <= 8'h0;
  else if (read_error_code_capture_reg)
    error_capture_code <= 8'h0;
  else if (set_bus_error_irq)
    error_capture_code <= {error_capture_code_type[7:6], error_capture_code_direction, error_capture_code_segment[4:0]};
end
assign error_capture_code_segment[0] = rx_idle | rx_ide | (rx_id2 & (bit_cnt<6'd13)) | rx_r1 | rx_r0 | rx_dlc | rx_ack | rx_ack_lim | error_frame & node_error_active;
assign error_capture_code_segment[1] = rx_idle | rx_id1 | rx_id2 | rx_dlc | rx_data | rx_ack_lim | rx_eof | rx_inter | error_frame & node_error_passive;
assign error_capture_code_segment[2] = (rx_id1 & (bit_cnt>6'd7)) | rx_rtr1 | rx_ide | rx_id2 | rx_rtr2 | rx_r1 | error_frame & node_error_passive | overload_frame;
assign error_capture_code_segment[3] = (rx_id2 & (bit_cnt>6'd4)) | rx_rtr2 | rx_r1 | rx_r0 | rx_dlc | rx_data | rx_crc | rx_crc_lim | rx_ack | rx_ack_lim | rx_eof | overload_frame;
assign error_capture_code_segment[4] = rx_crc_lim | rx_ack | rx_ack_lim | rx_eof | rx_inter | error_frame | overload_frame;
assign error_capture_code_direction  = ~transmitting;
always @ (bit_err or form_err or stuff_err) begin
  if (bit_err)
    error_capture_code_type[7:6] = 2'b00;
  else if (form_err)
    error_capture_code_type[7:6] = 2'b01;
  else if (stuff_err)
    error_capture_code_type[7:6] = 2'b10;
  else
    error_capture_code_type[7:6] = 2'b11;
end
assign set_bus_error_irq = go_error_frame & (~error_capture_code_blocked);
always @ (posedge clk or posedge rst) begin
  if (rst)
    error_capture_code_blocked <= 1'b0;
  else if (read_error_code_capture_reg)
    error_capture_code_blocked <= 1'b0;
  else if (set_bus_error_irq)
    error_capture_code_blocked <= 1'b1;
end
endmodule

